package com.ysg.http;

import android.os.Environment;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.ysg.base.BaseViewModel;
import com.ysg.constant.FileConstant;
import com.ysg.http.callback.OnErrorResult;
import com.ysg.http.callback.OnSuccessListResult;
import com.ysg.http.callback.OnSuccessResult;
import com.ysg.http.data.ApiService;
import com.ysg.http.data.download.ProgressCallBack;
import com.ysg.http.data.entity.config.AppConfig;
import com.ysg.utils.YBusBaseUtil;
import com.ysg.utils.YCollectionUtil;
import com.ysg.utils.YConfigUtil;
import com.ysg.utils.YRxUtils;
import com.ysg.utils.YSPUtils;
import com.ysg.utils.YStringUtil;
import com.ysg.utils.YToastUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.observers.DisposableObserver;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class HttpUtils {
    private volatile static HttpUtils mInstance;
    public HttpUtils(){
    }

    public static HttpUtils getInstance(){
        if (mInstance == null){
            synchronized (HttpUtils.class){
                if (mInstance == null){
                    mInstance = new HttpUtils();
                }
            }
        }
        return mInstance;
    }

    //====================================1.data：start================================================
    /**
     * 正常使用这个方法
     */
    public HttpUtils data(Observable observable, BaseViewModel viewModel, OnSuccessResult onSuccessResult){
        return data(observable, viewModel, onSuccessResult, null);
    }

    /**
     * 外部需要“错误回调时”使用这个方式
     */
    public HttpUtils data(Observable observable, BaseViewModel viewModel, OnSuccessResult onSuccessResult, OnErrorResult onErrorResult){
        data(true, observable, viewModel, onSuccessResult, onErrorResult);
        return this;
    }

    /**
     * observable:具体接口
     * BaseViewModel：对于ViewModel
     * 返回接口：OnSuccessResult
     */
    private HttpUtils data(boolean errorAgainFlag, Observable observable, BaseViewModel viewModel, OnSuccessResult onSuccessResult, OnErrorResult onErrorResult){
        observable
                .compose(YRxUtils.schedulersTransformer()) //线程调度
                .compose(YRxUtils.exceptionTransformer()) // 网络错误的异常转换, 这里可以换成自己的ExceptionHandle
                .doOnSubscribe(viewModel)//请求与ViewModel周期同步
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) {
                        if (viewModel != null){
                            viewModel.showDialog();
                        }
                    }
                })
                .subscribe(new DisposableObserver<BaseResponse>() {
                    @Override
                    public void onNext(BaseResponse response) {
                        if (response.isSuccess()){
                            if (onSuccessResult != null){
                                onSuccessResult.onSuccessResult(response);
                            }
                        }else{
                            String msg = response.getMsg();
                            if (YStringUtil.eq("1001", response.getCode())){
                                YToastUtil.showShort("请求异常，请重新登录");
                                YBusBaseUtil.logout();
                                return;
                            }
                            if (onErrorResult != null){
                                onErrorResult.onErrorResult(response.getCode(), msg);
                            }else {
                                YToastUtil.showLong(msg);
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        throwable.printStackTrace();
                        if (viewModel != null){
                            viewModel.dismissDialog();
                        }

                        if (onErrorResult != null){
                            onErrorResult.onErrorResult(0, throwable.getMessage());
                        }else {
                            YToastUtil.showLong(throwable.getMessage());
                        }

                        if (errorAgainFlag){
                            onChangeBaseUrl(throwable, new OnBaseUrlListener() {
                                @Override
                                public void onChangeSuccess() {
                                    data(false, observable, viewModel, onSuccessResult, onErrorResult);
                                }
                            });
                        }
                    }

                    @Override
                    public void onComplete() {
                        if (viewModel != null){
                            viewModel.dismissDialog();
                        }
                    }
                });
        return this;
    }




    //====================================2.List：start================================================
    /**
     * 正常使用这个方法
     */
    public HttpUtils list(Observable observable, BaseViewModel viewModel, OnSuccessListResult onSuccessListResult){
        return list(observable, viewModel, onSuccessListResult, null);
    }

    /**
     * 外部需要“错误回调时”使用这个方式
     */
    public HttpUtils list(Observable observable, BaseViewModel viewModel, OnSuccessListResult onSuccessListResult, OnErrorResult onErrorResult){
        return list(true, observable, viewModel, onSuccessListResult, onErrorResult);
    }

    /**
     * observable:具体接口
     * BaseViewModel：对于ViewModel
     * 返回接口：OnSuccessListResult
     */
    private HttpUtils list(boolean errorAgainFlag, Observable observable, BaseViewModel viewModel, OnSuccessListResult onSuccessListResult, OnErrorResult onErrorResult){
        observable
                .compose(YRxUtils.schedulersTransformer()) //线程调度
                .compose(YRxUtils.exceptionTransformer()) // 网络错误的异常转换, 这里可以换成自己的ExceptionHandle
                .doOnSubscribe(viewModel)//请求与ViewModel周期同步
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(Disposable disposable) {
                        viewModel.showDialog();
                    }
                })
                .subscribe(new DisposableObserver<BaseListResponse>() {
                    @Override
                    public void onNext(BaseListResponse response) {
                        if (response.isSuccess()) {
                            if (onSuccessListResult != null){
                                onSuccessListResult.onSuccessResult(response);
                            }
                        } else {
                            if (YStringUtil.eq("1001", response.getCode())){
                                YToastUtil.showShort("请求异常，请重新登录");
                                YBusBaseUtil.logout();
                                return;
                            }
                            if (onErrorResult != null){
                                onErrorResult.onErrorResult(0, "");
                            }else{
                                YToastUtil.showShort(response.getMsg());
                            }
                        }
                    }

                    @Override
                    public void onError(Throwable throwable) {
                        viewModel.dismissDialog();

                        if (onErrorResult != null){
                            onErrorResult.onErrorResult(0, "");
                        }else{
                            YToastUtil.showShort(throwable.getMessage());
                        }

                        if (errorAgainFlag){
                            onChangeBaseUrl(throwable, new OnBaseUrlListener() {
                                @Override
                                public void onChangeSuccess() {
                                    list(false,observable, viewModel, onSuccessListResult, onErrorResult);
                                }
                            });
                        }
                    }

                    @Override
                    public void onComplete() {
                        viewModel.dismissDialog();
                    }
                });
        return this;
    }


    //====================================3.处理baseUrl：start================================================
    public interface OnBaseUrlListener{
        void onChangeSuccess();
    }
    /**
     * 处理切换BaseUrl
     */
    private void onChangeBaseUrl(Throwable throwable, OnBaseUrlListener listener) {
//        if (throwable instanceof ResponseThrowable){
//            int code = ((ResponseThrowable) throwable).code;
//            if (code == ExceptionHandle.ERROR.TIMEOUT_ERROR){
//                requestBaseUrl(listener);
//            }
//        }
    }

    private void requestBaseUrl(OnBaseUrlListener listener){
        new Thread(()->{
            List<String> baseUrls = getBaseUrls();
            if (YCollectionUtil.isNotEmpty(baseUrls)){
                for (String url: baseUrls) {
                    try {
                        Request request = new Request.Builder().url(url + ApiService.iPTest).build();
                        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                                .connectTimeout(5, TimeUnit.SECONDS)
                                .build();
                        Response response = okHttpClient.newCall(request).execute();
                        if (response.code() == 200){
                            RetrofitClient.getInstance().setBaseUrl(url);
                            listener.onChangeSuccess();
                            return;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    private List<String> getBaseUrls(){
        List<String> baseUrls = new ArrayList<>();
        String appConfig = YSPUtils.getInstance().getString(FileConstant.app_config_file);
        if (YStringUtil.isNotEmpty(appConfig)){
            AppConfig config = JSON.parseObject(appConfig, AppConfig.class);
            if (config != null){
                String[] urls = config.getUrl();
                if (YCollectionUtil.isNotEmpty(urls)){
                    baseUrls = Arrays.asList(urls);
                    return baseUrls;
                }
            }
        }
        return baseUrls;
    }

    /**
     * 配置文件下载
     */
    public void onDownloadAppConfig() {
        DownLoadManager.getInstance().load(ApiService.app_config, true, new ProgressCallBack(FileConstant.app_config_dir, FileConstant.app_config_file) {
            @Override
            public void onSuccess(Object o) {
                Log.e("下载成功", "下载成功");
                RetrofitClient.getInstance().setBaseUrl(YConfigUtil.getBaseUrl());
            }

            @Override
            public void progress(long progress, long total) {
                Log.e("下载progress", "progress"+progress);
            }

            @Override
            public void onError(Throwable e) {
                Log.e("下载onError", "onError");
            }
        });
    }


















}
